﻿using UnityEngine;
using System.Collections;
using System.IO;
using System.Collections.Generic;
using System.Xml;

namespace Tools
{
    public class FileManager
    {
        public static string createDirectory(string path)
        {
            if (!string.IsNullOrEmpty(path))
            {
                if (!Directory.Exists(path))
                {
                    Directory.CreateDirectory(path);
                }
                return path;
            }
            return null;
        }

        public static bool deleteFile(string path)
        {
            if (!string.IsNullOrEmpty(path))
            {
                if (File.Exists(path))
                {
                    File.Delete(path);
                }
                return true;
            }
            return false;
        }

        public static bool isFileExits(string filePath)
        {
            return File.Exists(filePath);
        }

        public static bool compareTwoFiles(string file1, string file2)
        {
            if (!string.IsNullOrEmpty(file1) && !string.IsNullOrEmpty(file2) && isFileExits(file1) && isFileExits(file2))
            {
                return GX.MD5.ComputeHashStringFromFile(file1).Equals(GX.MD5.ComputeHashStringFromFile(file2));
            }
            return false;
        }

        public static bool deleteDirs(DirectoryInfo dirs)
        {
            if (dirs == null)
            {
                return false;
            }
            if (!dirs.Exists)
            {
                return true;
            }
            else
            {
                DirectoryInfo[] subDir = dirs.GetDirectories();
                if (subDir != null)
                {
                    for (int i = 0; i < subDir.Length; i++)
                    {
                        if (subDir[i] != null)
                        {
                            deleteDirs(subDir[i]);
                        }
                    }
                    subDir = null;
                }

                FileInfo[] files = dirs.GetFiles();
                if (files != null)
                {
                    for (int i = 0; i < files.Length; i++)
                    {
                        if (files[i] != null)
                        {
                            files[i].Delete();
                            files[i] = null;
                        }
                    }
                    files = null;
                }

                dirs.Delete();
                return true;
            }
        }

        public static bool fileCopy(string path, string target)
        {
            if (string.IsNullOrEmpty(path) || string.IsNullOrEmpty(target))
                return false;
            if (File.Exists(target))
                File.Delete(target);
            File.Copy(path, target);
            return true;
        }

        /// <summary>
        /// 将一个文件搬到另外一个指定目录下并且重MD5命名
        /// </summary>
        /// <param name="path">源文件的全路径</param>
        /// <param name="target">目标文件</param>
        /// <returns></returns>
        public static bool moveDirectioryFileToOtherWithNameChangeToMD5(string path, string target, bool isTreeMenu = true)
        {
            if (string.IsNullOrEmpty(path) || string.IsNullOrEmpty(target))
                return false;
            if (!Directory.Exists(target))
                FileManager.createDirectory(target);
            string md5 = GX.MD5.ComputeHashStringFromFile(path);
            string filetype = path.Substring(path.LastIndexOf('.'));
            if (isTreeMenu)
            {
                target = FileManager.createDirectory(target + "/" + md5.Substring(0, 2));
            }
            File.Copy(path, target + "/" + md5 + filetype);
            return true;
        }

        public static void getFilesInSomePath(string dirPath, string fileType, ref List<string> filePathList)
        {
            foreach(string path in Directory.GetFiles(dirPath))
            {
                if (Path.GetExtension(path) == fileType)
                {
                    filePathList.Add(path);
                }
            }
            if (Directory.GetDirectories(dirPath).Length > 0)  //遍历所有文件夹
            {
                foreach (string path in Directory.GetDirectories(dirPath))
                {
                    getFilesInSomePath(path, fileType, ref filePathList);
                }
            }
        }

        /// <summary>
        /// 深度遍历到所有的文件
        /// </summary>
        /// <param name="dirPath">文件路径</param>
        /// <param name="dirs"></param>
        /// <param name="olddirs"></param>
        /// <param name="fileType">文件类型</param>
        /// <returns></returns>
        public static Dictionary<string, string> GetDirs(string dirPath, ref List<string> dirs, string fileType, Dictionary<string, string> olddirs = null)
        {
            foreach (string path in Directory.GetFiles(dirPath))
            {
                if (System.IO.Path.GetExtension(path) == fileType)
                {
                    var newpath = path.Substring(path.IndexOf("Assets"));
                    dirs.Add(newpath);
                    if (olddirs != null)
                    {
                        var oldpath = newpath.Substring(newpath.IndexOf("/") + 1);
                        oldpath = oldpath.Replace('\\', '/');
                        if (olddirs.ContainsKey(oldpath) == false)
                            olddirs.Add(oldpath, GX.MD5.ComputeHashStringFromFile(path));
                    }
                }
            }

            if (Directory.GetDirectories(dirPath).Length > 0)  //遍历所有文件夹
            {
                foreach (string path in Directory.GetDirectories(dirPath))
                {
                    GetDirs(path, ref dirs, fileType, olddirs);
                }
            }
            return olddirs;
        }

        /// <summary>
        /// 写入一个AB文件到本地存储
        /// </summary>
        /// <param name="path">文件路径</param>
        /// <param name="name">文件名</param>
        /// <param name="info">文件的二进制信息</param>
        /// <param name="length">长度</param>
        public static bool saveOneAssetBundleToLocalFile(string path, string name, byte[] info, int length, bool isTreeMenu = false)
        {
            Stream sw;
            string filepath = null;
            if (!Directory.Exists(path))
                createDirectory(path);
            if (isTreeMenu)
            {
                var newpath = "/" + name.Substring(0, 2);
                filepath = FileManager.createDirectory(path + newpath) + "/" + name;
            }
            else
                filepath = path + "/" + name;
            FileInfo t = new FileInfo(filepath);
            if (t.Exists)
            {
                File.Delete(filepath);
            }
            sw = t.Create();
            sw.Write(info, 0, length);
            sw.Close();
            sw.Dispose();
            return true;
        }

        public static bool SaveFile(string path, string name, byte[] info, int length)
        {
            if (!Directory.Exists(path))
                createDirectory(path);
            Stream sw;
            FileInfo fileInfo = new FileInfo(path + "/" + name);
            if (fileInfo.Exists)
            {
                fileInfo.Delete();
            }
            sw = fileInfo.Create();
            sw.Write(info, 0, length);
            sw.Close();
            sw.Dispose();
            return true;
        }
    }
}
